#!/usr/bin/python
# Translate strings to Morse code, with customisable output.
#
# Copyright (C) 2013 Anselm Lingnau <anselm@anselms.net>

_code_tab = """
  A .- B -... C -.-. D -.. E .
  F ..-. G --. H .... I .. J .---
  K -.- L .-.. M -- N -. O ---
  P .--. Q --.- R .-. S ... T -
  U ..- V ...- W .-- X -..- Y -.--
  Z --..
"""

# This is special magic to initialise a dictionary from the string.
_code = dict(zip(*[iter(_code_tab.split())]*2))

def to_morse(words=[], dit='.', dah='-',
             cspace='', lspace=' ', wspace='\n', end='', default=''):
    """Translate a string to Morse code."""
    s = " ".join(words) if isinstance(words, list) else words
    if not len(s): return default
    result = []
    for word in s.upper().split():
        w = []
        for c in word:
            w.append(cspace.join([dit if dd == '.' else dah
                                      for dd in _code[c]]))
        result.append(lspace.join(w))
    return wspace.join(result) + end

if __name__ == "__main__":
    import argparse
    mode_options = {
        'pi': { 'dit': 'b', 'dah': 'bbb', 'cspace': 'x', 'lspace': 'xxx',
                'wspace': 'xxxxxxx', 'end': 'q' },
    }
    class ModeAction(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            for k in mode_options[values]:
                setattr(namespace, k, mode_options[values][k])
    parser = argparse.ArgumentParser(description='Translate to Morse code.')
    parser.add_argument('words', metavar='WORD', nargs='+',
                        help='A word to be translated')
    parser.add_argument('--dit', dest='dit',
                        default='.', help='Symbol for short signal (dot)')
    parser.add_argument('--dah', dest='dah',
                        default='-', help='Symbol for long signal (dash)')
    parser.add_argument('--cspace', dest='cspace',
                        default='', help='Inter-signal space')
    parser.add_argument('--lspace', dest='lspace',
                        default=' ', help='Inter-letter space')
    parser.add_argument('--wspace', dest='wspace',
                        default='\n', help='Inter-word space')
    parser.add_argument('--end', dest='end',
                        default='', help='End marker')
    parser.add_argument('--mode', action=ModeAction, default=argparse.SUPPRESS,
                        help='Set mode MODE')
    parser.add_argument('--default', dest='default', default='',
                        help='What to output if no arguments are given')
    args = parser.parse_args()
    print to_morse(**vars(args))
